package com.qen.encrypt.utils;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.qen.encrypt.filter.DecryptRequestFilter;
import com.qen.encrypt.inter.EncryptGroup;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * 手动解密功能
 */
public class EncryptUtils {

    /**
     * 手动解密操作.单参数.
     *
     * @param request 操作
     * @param param   加密的参数
     * @return 解密后的参数
     */
    public static String decryptParam(HttpServletRequest request, String param) {
        if (StrUtil.isBlank(param)) {
            return param;
        }
        try {
            RequestMappingHandlerMapping mapping = SpringUtil.getBean(RequestMappingHandlerMapping.class);
            DecryptRequestFilter decryptRequestFilter = SpringUtil.getBean(DecryptRequestFilter.class);
            HandlerExecutionChain chain = mapping.getHandler(request);
            if (chain != null) {
                Object handler = chain.getHandler();
                if (handler instanceof HandlerMethod) {
                    HandlerMethod handlerMethod = (HandlerMethod) handler;

                    Method method = handlerMethod.getMethod();
                    Class<?> controller = handlerMethod.getBeanType();

//                    Map<String, String> groupKeyMap = decryptRequestFilter.getGroupKeyMap();
//                    String key = decryptRequestFilter.getEncryptConfig().getDefaultKey();
                    ParamEncrypt encrypt = decryptRequestFilter.getEncryptMapConfig().getParamEncrypt();
                    if (method.isAnnotationPresent(EncryptGroup.class)) {
                        String group = method.getAnnotation(EncryptGroup.class).value();
                        if (StrUtil.isNotBlank(group)) {
//                            key = groupKeyMap.get(group);
                            encrypt = decryptRequestFilter.getEncryptMapConfig().getParamEncrypt(group);
                        }
                    } else if (controller.isAnnotationPresent(EncryptGroup.class)) {
                        String group = controller.getAnnotation(EncryptGroup.class).value();
                        if (StrUtil.isNotBlank(group)) {
//                            key = groupKeyMap.get(group);
                            encrypt = decryptRequestFilter.getEncryptMapConfig().getParamEncrypt(group);
                        }
                    }

                    return encrypt.priDecrypt(param);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return param;
        }
        return param;
    }

    /**
     * 手动解密操作.批量Map.
     *
     * @param request 操作
     * @param param   加密的参数
     * @return 解密后的参数
     */
    public static Map<String, String> decryptParam(HttpServletRequest request, Map<String, String> param) {
        try {
            RequestMappingHandlerMapping mapping = SpringUtil.getBean(RequestMappingHandlerMapping.class);
            DecryptRequestFilter decryptRequestFilter = SpringUtil.getBean(DecryptRequestFilter.class);
            HandlerExecutionChain chain = mapping.getHandler(request);
            if (chain != null) {
                Object handler = chain.getHandler();
                if (handler instanceof HandlerMethod) {
                    HandlerMethod handlerMethod = (HandlerMethod) handler;

                    Method method = handlerMethod.getMethod();
                    Class<?> controller = handlerMethod.getBeanType();

//                    Map<String, String> groupKeyMap = decryptRequestFilter.getGroupKeyMap();
//                    String key = decryptRequestFilter.getEncryptConfig().getDefaultKey();
                    ParamEncrypt encrypt = decryptRequestFilter.getEncryptMapConfig().getParamEncrypt();

                    if (method.isAnnotationPresent(EncryptGroup.class)) {
                        String group = method.getAnnotation(EncryptGroup.class).value();
                        if (StrUtil.isNotBlank(group)) {
                            encrypt = decryptRequestFilter.getEncryptMapConfig().getParamEncrypt(group);
                        }
                    } else if (controller.isAnnotationPresent(EncryptGroup.class)) {
                        String group = controller.getAnnotation(EncryptGroup.class).value();
                        if (StrUtil.isNotBlank(group)) {
                            encrypt = decryptRequestFilter.getEncryptMapConfig().getParamEncrypt(group);
                        }
                    }

                    Map<String, String> result = new HashMap<>();
                    for (String s : param.keySet()) {
                        String v = param.get(s);
                        if (StrUtil.isBlank(v)) {
                            result.put(s, v);
                        } else {
                            result.put(s, encrypt.priDecrypt(param.get(s)));
                        }
                    }
                    return result;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return param;
        }
        return param;
    }

}
